package com.hhxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhxy.constants.SystemConstants;
import com.hhxy.handler.exception.CustomException;
import com.hhxy.mapper.CategoryMapper;
import com.hhxy.model.dto.CategoryDto;
import com.hhxy.model.entity.Article;
import com.hhxy.model.entity.Category;
import com.hhxy.model.vo.CategoryVo;
import com.hhxy.model.vo.PageVo;
import com.hhxy.service.ArticleService;
import com.hhxy.service.CategoryService;
import com.hhxy.utils.BeanCopyUtils;
import com.hhxy.utils.response.AppHttpCodeEnum;
import com.hhxy.utils.response.ResponseResult;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author ghp
 * @description 针对表【tb_category(分类表)】的数据库操作Service实现
 * @createDate 2023-04-25 11:58:40
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Resource
    private ArticleService articleService;

    /**
     * 查询已发布文章的分类
     *
     * @return
     */
    @Override
    public ResponseResult getCategoryList() {
        // 查询已发布的文章
        List<Article> articleList = articleService.list(new LambdaQueryWrapper<Article>()
                .eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL));
        // 获取已发布文章的分类id，并且去重
        Set<Long> categoryIds = articleList.stream()
                .map(article -> article.getCategoryId())
                .collect(Collectors.toSet());

        // 查询已发布文章的分类（分类要处于正常状态，这里采用stream流进行过滤了，也可以使用条件查询）
        // 方式一：
        List<Category> categoryList = this.listByIds(categoryIds).stream()
                .filter(category -> SystemConstants.CATEGORY_STATUS_NORMAL.equals(category.getStatus()))
                .collect(Collectors.toList());
        // 方式二：
//        List<Category> categoryList = this.list(new LambdaQueryWrapper<Category>()
//                .eq(Category::getStatus, SystemConstants.CATEGORY_STATUS_NORMAL));

        // 封装VO
        List<CategoryVo> categoryVos = BeanCopyUtils.copyBeanList(categoryList, CategoryVo.class);

        return ResponseResult.okResult(categoryVos);
    }

    /**
     * 分页条件查询文章分类
     */
    @Override
    public ResponseResult list(Integer pageNum, Integer pageSize, String name, String status) {
        // 分页条件查询出分类
        Page<Category> page = new Page<>(pageNum, pageSize);
        this.page(page, new LambdaQueryWrapper<Category>()
                .like(StringUtils.hasText(name), Category::getName, name)
                .eq(StringUtils.hasText(status), Category::getStatus, status)
                .orderByDesc(Category::getUpdateTime));
        // 封装VO
        List<CategoryVo> categoryVos = BeanCopyUtils.copyBeanList(page.getRecords(), CategoryVo.class);
        return ResponseResult.okResult(new PageVo<CategoryVo>(categoryVos, page.getTotal()));
    }

    /**
     * 根据id删除分类
     *
     * @param ids
     * @return
     */
    @Override
    public ResponseResult deleteCategoryByIds(Long[] ids) {
        boolean flag = this.removeByIds(Arrays.asList(ids));
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_DELETE_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_DELETE);
    }

    /**
     * 根据id查询分类
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult getCategoryById(Long id) {
        Category category = this.getById(id);
        CategoryVo categoryVo = BeanCopyUtils.copyBean(category, CategoryVo.class);
        return ResponseResult.okResult(categoryVo);
    }

    /**
     * 根据id修改分类
     *
     * @param categoryDto
     * @return
     */
    @Override
    public ResponseResult updateCategoryById(CategoryDto categoryDto) {
        Category category = BeanCopyUtils.copyBean(categoryDto, Category.class);
        boolean flag = this.updateById(category);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_UPDATE_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_UPDATE);
    }

    /**
     * 新增分类
     *
     * @param categoryDto
     * @return
     */
    @Override
    public ResponseResult add(CategoryDto categoryDto) {
        Category category = BeanCopyUtils.copyBean(categoryDto, Category.class);
        // 判断已逻辑删除的记录中是否存在该分类
        Category c = this.getBaseMapper().selectDeletedCategoryByName(category.getName());
        if (Objects.nonNull(c)) {
            // 新增的分类存在于已被逻辑删除的记录中，直接更新即可
            c.setName(category.getName());
            c.setDescription(category.getDescription());
            boolean flag = this.getBaseMapper().updateDeletedCategoryById(c);
            if (!flag) {
                throw new CustomException(AppHttpCodeEnum.SERVICE_INSERT_ERROR);
            }
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_INSERT);
        }

        // 逻辑删除的记录中不存在该记录，直接新增
        boolean flag = this.save(category);
        if (!flag) {
            throw new CustomException(AppHttpCodeEnum.SERVICE_INSERT_ERROR);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS_INSERT);
    }
}




